package top.syfy.bili.fbm.util;

import cn.hutool.core.util.StrUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * ffmpegUtil工具类
 *
 * @author syfy
 * @date 2021/02/02
 */
public class FfmpegUtil {

    /**
     * 通过Java调用ffmpeg命令
     *
     * @param ffmpeg    ffmpeg命令可执行文件的所在路径
     * @param videoPart 缓存文件的视频文件的路径
     * @param audioPart 缓存文件的音频文件的路径
     * @param outFile   缓存文件的视频、音频合并后生成的文件
     */
    public static Process mergeM4S(String ffmpeg, String videoPart, String audioPart, String outFile) throws IOException {
        if (Objects.isNull(ffmpeg) || Objects.isNull(videoPart) || Objects.isNull(audioPart) || Objects.isNull(outFile)) {
            return null;
        }
        ProcessBuilder processBuilder = new ProcessBuilder();
        List<String> command = new ArrayList<>();
        /*
         * ffmpeg将音频和视频文件进行合并的命令(含参数)如下：
         *      ffmpeg -i 视频文件名 -i 音频文件名 -c:v copy -strict experimental 输出文件名
         *      ffmpeg -i 视频文件名 -i 音频文件名 -codec copy 输出文件名
         *
         *      -y (global)     Overwrite output files without asking.
         */
        command.add(ffmpeg);
        command.add("-i");
        command.add(videoPart);
        command.add("-i");
        command.add(audioPart);
        command.add("-codec");
        command.add("copy");
        command.add(outFile);
        command.add("-y");
        processBuilder.command(command);
        processBuilder.redirectErrorStream(true);
        processBuilder.inheritIO();
        return processBuilder.start();
    }

    /**
     * 获取操作系统结束系统进程的命令的绝对路径
     */
    private static String getKillCommandPath() {
        String killCommandPath;
        // 获取操作系统名称
        String osName = System.getProperty("os.name");
        if (StrUtil.startWithIgnoreCase(osName, "Windows")) {
            killCommandPath = "C:\\Windows\\System32\\tskill.exe";
        } else if (StrUtil.startWithIgnoreCase(osName, "linux")) {
            killCommandPath = "/usr/bin/kill";
        } else if (StrUtil.startWithIgnoreCase(osName, "Mac")) {
            killCommandPath = "/bin/kill";
        } else {
            throw new RuntimeException("Unknown operating system");
        }
        return killCommandPath;
    }

    /**
     * 通过命令[tskill/kill PID]的方式关闭启动的ffmpeg进程
     * @param process 进程(主要获取进程的PID)
     */
    public static void destroy(Process process) throws IOException {
        //RuntimeUtil.execForStr(FfmpegUtil.getKillCommandPath() + ' ' + process.pid());
        ProcessBuilder builder = new ProcessBuilder();
        List<String> commands = new ArrayList<>();
        commands.add(getKillCommandPath());
        commands.add(String.valueOf(process.pid()));
        builder.command(commands);
        builder.redirectErrorStream(true);
        builder.inheritIO();
        builder.start();
    }

}